import { createRouter, createWebHashHistory } from 'vue-router'
import type {
  Router,
  RouteLocationNormalized,
  RouteRecordNormalized,
  RouteMeta,
  RouteRecordRaw
} from 'vue-router'
import { isUrl } from '@/utils/is'
import { omit, cloneDeep } from 'lodash-es'
import { usePermissionStoreWithOut } from '@/store/modules/permission'

const permissionStore = usePermissionStoreWithOut()

const modules = import.meta.glob('../views/**/*.{vue,tsx}')

/* Layout */
export const Layout = () => import('@/layout/Layout.vue')

export const getParentLayout = () => {
  return () =>
    new Promise((resolve) => {
      resolve({
        name: 'ParentLayout'
      })
    })
}

export const getRawRoute = (route: RouteLocationNormalized): RouteLocationNormalized => {
  if (!route) return route
  const { matched, ...opt } = route
  return {
    ...opt,
    matched: (matched
      ? matched.map((item) => ({
          meta: item.meta,
          name: item.name,
          path: item.path
        }))
      : undefined) as RouteRecordNormalized[]
  }
}

// 前端控制路由生成
export const generateRoutesFn1 = (
  routes: AppRouteRecordRaw[],
  keys: string[],
  basePath = '/'
): AppRouteRecordRaw[] => {
  const res: AppRouteRecordRaw[] = []

  for (const route of routes) {
    const meta = route.meta as RouteMeta
    // skip some route
    if (meta.hidden && !meta.canTo) {
      continue
    }

    let data: Nullable<AppRouteRecordRaw> = null

    let onlyOneChild: Nullable<string> = null
    if (route.children && route.children.length === 1 && !meta.alwaysShow) {
      onlyOneChild = (
        isUrl(route.children[0].path)
          ? route.children[0].path
          : pathResolve(pathResolve(basePath, route.path), route.children[0].path)
      ) as string
    }

    // 开发者可以根据实际情况进行扩展
    for (const item of keys) {
      // 通过路径去匹配
      if (isUrl(item) && (onlyOneChild === item || route.path === item)) {
        data = Object.assign({}, route)
      } else {
        const routePath = pathResolve(basePath, onlyOneChild || route.path)
        if (routePath === item || meta.followRoute === item) {
          data = Object.assign({}, route)
        }
      }
    }

    // recursive child routes
    if (route.children && data) {
      data.children = generateRoutesFn1(route.children, keys, pathResolve(basePath, data.path))
    }
    if (data) {
      res.push(data as AppRouteRecordRaw)
    }
  }
  return res
}

// 查找是否有权限的菜单（未配置permissions不需要权限校验）
const hasPermissions = (permissions: any) => {
  const allPermissions = permissionStore.getPermissions
  const ps = [permissions].flat().filter((x) => !!x)
  return ps.length < 1 || allPermissions.some((x: any) => ps.includes(x))
}

// 根据navigation配置动态生成routers菜单
export const formatRoutes = function (navs: Array<any>) {
  const results: Array<any> = []
  const genRoutes = function (routers: Array<any>, res, parent) {
    let isRoot = false
    // 根目录
    if (!res) {
      res = results
      isRoot = true
    }
    routers?.forEach((nav) => {
      if (!hasPermissions(nav.permissions)) {
        return
      }
      let route
      // 如果根目录只有一个节点，增加一层Layout
      if (isRoot && nav.module && nav.subpages?.length < 1) {
        route = {
          path: '/' + nav.key,
          component: Layout,
          meta: {
            hidden: nav.hidden,
            title: nav.name,
            icon: nav.logo,
            noCache: nav.noCache,
            roles: []
          },
          children: [
            {
              path: 'index',
              component: () =>
                import('@/views/Default.vue').then((c) => ({
                  ...c.default,
                  name: nav.key + '.index'
                })),
              name: nav.key + '.index',
              meta: {
                hidden: nav.hidden,
                title: nav.name,
                icon: nav.logo,
                noCache: nav.noCache,
                roles: [],
                config: nav
              }
            }
          ]
        }
        if (nav.module === 'default') {
          route.children[0].component = () =>
            import('@/views/Default.vue').then((c) => ({
              ...c.default,
              name: nav.key + '.index'
            }))
        } else if (nav.module) {
          try {
            // const comModule =
            //   modules[`../views/${nav.module}.vue`] || modules[`../views/${nav.module}.tsx`]
            // const component = nav.module as string
            // if (!comModule && !component.includes('#')) {
            //   console.error(`未找到${nav.module}.vue文件或${nav.module}.tsx文件，请创建`)
            // } else {
            //   // 动态加载路由文件，可根据实际情况进行自定义逻辑
            //   route.children[0].component =
            //     component === '#'
            //       ? Layout
            //       : component.includes('##')
            //       ? getParentLayout()
            //       : comModule().then((c: any) => ({
            //           ...c.default,
            //           name: nav.key + '.index'
            //         }))
            // }
            const splitName = nav.module.split('/')
            route.children[0].component = () =>
              import(`../views/${splitName[0]}/${splitName[1]}.vue`).then((c) => ({
                ...c.default,
                name: nav.key + '.index'
              }))
          } catch (e) {
            console.error(`未找到${nav.module}.vue文件，请创建`)
            console.error(e)
          }
        }
      } else {
        route = {
          path: (isRoot ? '/' : '') + nav.key,
          name: parent ? parent.name + '.' + nav.key : nav.key,
          meta: {
            hidden: nav.hidden,
            title: nav.name,
            icon: nav.logo,
            noCache: nav.noCache,
            roles: [],
            config: nav
          }
        }
        if (isRoot) {
          route.component = Layout
        } else if (nav.module === 'default') {
          route.component = () =>
            import('@/views/Default.vue').then((c) => ({
              ...c.default,
              name: parent ? parent.name + '.' + nav.key : nav.key
            }))
        } else if (nav.module) {
          try {
            // const comModule =
            //   modules[`../views/${nav.module}.vue`] || modules[`../views/${nav.module}.tsx`]
            // const component = nav.module as string
            // if (!comModule && !component.includes('#')) {
            //   console.error(`未找到${nav.module}.vue文件或${nav.module}.tsx文件，请创建`)
            // } else {
            //   // 动态加载路由文件，可根据实际情况进行自定义逻辑
            //   route.component =
            //     component === '#'
            //       ? Layout
            //       : component.includes('##')
            //       ? getParentLayout()
            //       : comModule().then((c: any) => ({
            //           ...c.default,
            //           name: parent ? parent.name + '.' + nav.key : nav.key
            //         }))
            // }
            const splitName = nav.module.split('/')
            route.component = () =>
              import(`../views/${splitName[0]}/${splitName[1]}.vue`).then((c) => ({
                ...c.default,
                name: parent ? parent.name + '.' + nav.key : nav.key
              }))
          } catch (e) {
            console.error(`未找到${nav.module}.vue文件，请创建`)
            console.error(e)
          }
        }
        route.children = []
      }
      res.push(route)
      genRoutes(nav.subpages, route.children, route)
    })
  }
  genRoutes(navs, null, null)
  return results
}

// 找到第一个路由
export function getFirstPath(routes: Array<any>) {
  const paths: Array<String> = []
  let first = routes[0]
  while (first) {
    paths.push(first.path)
    if (first.children && first.children[0]) {
      first = first.children[0]
    } else {
      first = null
    }
  }
  return paths.join('/')
}
// 后端控制路由生成
export const generateRoutesFn2 = (routes: AppCustomRouteRecordRaw[]): AppRouteRecordRaw[] => {
  const res: AppRouteRecordRaw[] = []

  for (const route of routes) {
    const data: AppRouteRecordRaw = {
      path: route.path,
      name: route.name,
      redirect: route.redirect,
      meta: route.meta
    }
    if (route.component) {
      const comModule = modules[`../${route.component}.vue`] || modules[`../${route.component}.tsx`]
      const component = route.component as string
      if (!comModule && !component.includes('#')) {
        console.error(`未找到${route.component}.vue文件或${route.component}.tsx文件，请创建`)
      } else {
        // 动态加载路由文件，可根据实际情况进行自定义逻辑
        data.component =
          component === '#' ? Layout : component.includes('##') ? getParentLayout() : comModule
      }
    }
    // recursive child routes
    if (route.children) {
      data.children = generateRoutesFn2(route.children)
    }
    res.push(data as AppRouteRecordRaw)
  }
  return res
}

export const pathResolve = (parentPath: string, path: string) => {
  if (isUrl(path)) return path
  const childPath = path.startsWith('/') || !path ? path : `/${path}`
  return `${parentPath}${childPath}`.replace(/\/\//g, '/')
}

// 路由降级
export const flatMultiLevelRoutes = (routes: AppRouteRecordRaw[]) => {
  const modules: AppRouteRecordRaw[] = cloneDeep(routes)
  for (let index = 0; index < modules.length; index++) {
    const route = modules[index]
    if (!isMultipleRoute(route)) {
      continue
    }
    promoteRouteLevel(route)
  }
  return modules
}

// 层级是否大于2
const isMultipleRoute = (route: AppRouteRecordRaw) => {
  if (!route || !Reflect.has(route, 'children') || !route.children?.length) {
    return false
  }

  const children = route.children

  let flag = false
  for (let index = 0; index < children.length; index++) {
    const child = children[index]
    if (child.children?.length) {
      flag = true
      break
    }
  }
  return flag
}

// 生成二级路由
const promoteRouteLevel = (route: AppRouteRecordRaw) => {
  let router: Router | null = createRouter({
    routes: [route as RouteRecordRaw],
    history: createWebHashHistory()
  })

  const routes = router.getRoutes()
  addToChildren(routes, route.children || [], route)
  router = null

  route.children = route.children?.map((item) => omit(item, 'children'))
}

// 添加所有子菜单
const addToChildren = (
  routes: RouteRecordNormalized[],
  children: AppRouteRecordRaw[],
  routeModule: AppRouteRecordRaw
) => {
  for (let index = 0; index < children.length; index++) {
    const child = children[index]
    const route = routes.find((item) => item.name === child.name)
    if (!route) {
      continue
    }
    routeModule.children = routeModule.children || []
    if (!routeModule.children.find((item) => item.name === route.name)) {
      routeModule.children?.push(route as unknown as AppRouteRecordRaw)
    }
    if (child.children?.length) {
      addToChildren(routes, child.children, routeModule)
    }
  }
}

// 基于toRoute，生成一条无ui的根路由
export const getWithoutRoute = (to: any) => {
  const splitName = to.path.split('/').reverse()
  return {
    path: to.path,
    name: to.path,
    children: [],
    component: () =>
      import(`../views/${splitName[1]}/${splitName[0]}.vue`).then((c) => ({
        ...c.default,
        name: to.path
      })),
    meta: {
      hidden: true,
      title: to.query?.title || '',
      noCache: true,
      roles: []
    }
  }
}
